﻿using System;
using OnlineGameLibrary.Game;
using System.ServiceModel.Channels;
using OnlineGameLibrary.Contract;
using KaKaSongGame.ViewModel;
using System.Linq;
using KKSGameLibrary.Logic;
using KakaSongGame;
using KakaSongGame.Contract;
using OnlineGameLibrary.MessageEx;
using System.Windows;

namespace KaKaSongGame
{
	public class KakaSongGame1:GameBase
	{
		MainPage _mainpagev;
		MainPageViewModel _mainpagevm;
		TimeSpan playerwaitingtime;
		int puppetcount;

		public KakaSongGame1(GameRoom gameroom, Player curplayer, IPlayerDuplexChannel channel)
			: base(gameroom, curplayer, channel)
		{
			playerwaitingtime = TimeSpan.FromSeconds((int)gameroom.GameConfig.ConfigDict[GlobalConst.PlayerWaitingTime_Config]);
			puppetcount = (int)gameroom.GameConfig.ConfigDict[GlobalConst.PlayerPuppetCount_Config];

			var gplist = from p in GameRoom.Players
				select new GamePlayer(p.PlayerID, p.PlayerDisplayName);

			_mainpagevm = new MainPageViewModel(gplist.ToList(), curplayer.PlayerID, puppetcount, playerwaitingtime, onPlayerSendMessage);
            _mainpagevm.GameInfo = gameroom.GameInfo;

			_mainpagev = new MainPage();
			_mainpagev.DataContext = _mainpagevm;
		}

		public override FrameworkElement GameUI
		{
			get
			{
				return _mainpagev;
			}
			protected set
			{
				throw new NotImplementedException();
			}
		}

        // implement GameBase.onPlayerAction method
		public override void onPlayerAction(string playername, DateTime duetime, Message message)
		{
			string action = message.GetAction();
			string curplayerid = message.GetAudience().First();
			var curplayervm = getPlayerVM(curplayerid);

			setAllPlayerWaiting();

			if (action == KKSGameMessageDefines.REQUEST_PUT_CARD.Action)
			{
				var card = KKSGameMessageDefines.REQUEST_PUT_CARD.GetMessage(message).MessageBodyContent as Card;

				GameUI.Dispatcher.BeginInvoke(delegate
				{
					curplayervm.PlayerState = PlayerVMState.PutCard;
					curplayervm.CardInMap = new CardInMap { Card = card };

					_mainpagevm.PlayerActionUI.SetCardCandidate(card, curplayervm.GamePlayer);
				});
			}
			else if (action == KKSGameMessageDefines.REQUEST_PUT_PUPPET.Action)
			{
				GameUI.Dispatcher.BeginInvoke(delegate
				{
					curplayervm.PlayerState = PlayerVMState.PutPuppet;
					//if (curplayerid == _mainpagevm.PlayerMe.ID)
						_mainpagevm.PlayerActionUI.SetPuppetCandidate(curplayervm.GamePlayer);
				});
			}
			else if (action == KKSGameMessageDefines.RESPONSE_PUT_CARD.Action)
			{
				var gplayervm = getPlayerVM(curplayerid);
				var cardim = KKSGameMessageDefines.RESPONSE_PUT_CARD.GetMessage(message).MessageBodyContent as CardInMap;

				GameUI.Dispatcher.BeginInvoke(delegate
				{
					if (cardim != null)
					{
						if (!_mainpagevm.CardMap.TestSetCard(cardim))
						{
							MessageBox.Show("cannot put here");
							return;
						}

						gplayervm.CardInMap = cardim;
						gplayervm.PlayerState = PlayerVMState.PutCardComplete;

						_mainpagevm.CardMap.SetCard(cardim, gplayervm.GamePlayer);
						_mainpagevm.PlayerActionUI.SetCard(cardim, gplayervm.GamePlayer);
					}
					else
					{
						gplayervm.PlayerState = PlayerVMState.Timeout;

						//_mainpagevm.PlayerActionUI.PlayerActionTimeout(gplayervm.GamePlayer);
					}
				});
			}
			else if (action == KKSGameMessageDefines.RESPONSE_PUT_PUPPET.Action)
			{
				var gplayervm = getPlayerVM(curplayerid);
				var puppet = KKSGameMessageDefines.RESPONSE_PUT_PUPPET.GetMessage(message).MessageBodyContent as PuppetOperation;

				GameUI.Dispatcher.BeginInvoke(delegate
				{
					if (puppet != null)
					{
						if (!puppet.IsPutPuppet)
						{
							//
						}
						else
						{
							var region = _mainpagevm.CardMap.GetRegion(puppet.Row, puppet.Column, puppet.Direction);
							if (region == null)
							{
								MessageBox.Show("cannot put here");
								return;
							}
							if (!_mainpagevm.CardMap.TestSetOwner(region, gplayervm.GamePlayer))
							{
								MessageBox.Show("cannot put here");
								return;
							}

							gplayervm.PlayerState = PlayerVMState.PutPuppetComplete;
							gplayervm.PuppetOperation = puppet;

							_mainpagevm.CardMap.SetOwner(puppet.Row, puppet.Column, puppet.Direction, gplayervm.GamePlayer);
							_mainpagevm.PlayerActionUI.SetOwner(puppet.Row, puppet.Column, puppet.Direction, gplayervm.GamePlayer);
						}
					}
					else
					{
						gplayervm.PlayerState = PlayerVMState.Timeout;
						//_mainpagevm.PlayerActionUI.PlayerActionTimeout(gplayervm.GamePlayer);
					}
				});
			}
		}

		public override void GameEnd()
		{
            _mainpagev.Dispatcher.BeginInvoke(delegate
            {
                _mainpagev.dashboard.Visibility = Visibility.Visible;
            });
		}

		void onPlayerSendMessage(Message msg)
		{
			base.SendMessageToGameServer(msg);
		}

		public override void onGameAction(DateTime duetime, Message msg)
		{
			base.onGameAction(duetime, msg);
		}

		public override void DisposeGame()
		{
			base.DisposeGame();
		}

		public override void onPlayerLeave(string playername)
		{
			_mainpagev.Dispatcher.BeginInvoke(delegate
			{
				var playervm = getPlayerVM(playername);
				playervm.PlayerState = PlayerVMState.Leave;
			});
		}

		void setAllPlayerWaiting()
		{
			GameUI.Dispatcher.BeginInvoke(delegate
			{
				foreach (var gpvm in _mainpagevm.PlayerList)
					if (gpvm.PlayerState != PlayerVMState.Leave)
						gpvm.PlayerState = PlayerVMState.Waiting;
			});
		}

		PlayerViewModel getPlayerVM(string playerid)
		{
			return this._mainpagevm.PlayerList
				.First(p => p.GamePlayer.ID == playerid);
		}
	}
}
